package io.github.junxworks.qt.modules.data.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.google.common.collect.Lists;

import io.github.junxworks.ep.core.utils.HttpClientUtil;
import io.github.junxworks.junx.core.util.DateUtils;
import io.github.junxworks.junx.core.util.StringUtils;
import io.github.junxworks.qt.config.QtConfig;
import io.github.junxworks.qt.modules.data.entity.DStockRealtime;
import io.github.junxworks.qt.modules.data.service.RealtimeService;
import io.github.junxworks.qt.modules.tushare.mapper.BaseInfoMapper;

/**
 *
 *数据格式：var hq_str_sz002307="北新路桥,8.700,8.820,9.080,9.310,8.630,9.080,9.100,108452484,968707402.800,42300,9.080,91100,9.070,17500,9.060,42200,9.050,19200,9.040,7048,9.100,16600,9.110,47300,9.120,20460,9.130,21400,9.140,2019-03-27,14:33:03,00";
0：”大秦铁路”，股票名字；
1：”27.55″，今日开盘价；
2：”27.25″，昨日收盘价；
3：”26.91″，当前价格；
4：”27.55″，今日最高价；
5：”26.20″，今日最低价；
6：”26.91″，竞买价，即“买一”报价；
7：”26.92″，竞卖价，即“卖一”报价；
8：”22114263″，成交的股票数，由于股票交易以一百股为基本单位，所以在使用时，通常把该值除以一百；
9：”589824680″，成交金额，单位为“元”，为了一目了然，通常以“万元”为成交金额的单位，所以通常把该值除以一万；
10：”4695″，“买一”申请4695股，即47手；
11：”26.91″，“买一”报价；
12：”57590″，“买二”
13：”26.90″，“买二”
14：”14700″，“买三”
15：”26.89″，“买三”
16：”14300″，“买四”
17：”26.88″，“买四”
18：”15100″，“买五”
19：”26.87″，“买五”
20：”3100″，“卖一”申报3100股，即31手；
21：”26.92″，“卖一”报价
(22, 23), (24, 25), (26,27), (28, 29)分别为“卖二”至“卖四的情况”
30：”2008-01-11″，日期；
31：”15:05:32″，时间；
 * 
 * 
 * @program :springbootdev
 * @description:
 * @author:Junxworks
 * @create:2019-08-17 10:54
 */
@Service("StockRealtimeService")
public class RealtimeServiceImpl implements RealtimeService {

	private Logger log = LoggerFactory.getLogger(RealtimeServiceImpl.class);

	@Autowired
	private QtConfig config;

	@Autowired
	private BaseInfoMapper profileMapper;

	private static final int stockName = 0;

	private static final int openingPrice = 1;

	private static final int closingPriceY = 2;

	private static final int currentPrice = 3;

	private static final int highestPrice = 4;

	private static final int lowestPrice = 5;

	private static final int buyingPrice = 6;

	private static final int buyOneVolume = 10;

	private static final int sellingPrice = 7;

	private static final int tradeVolume = 8;

	private static final int tradeAmount = 9;

	private static final int sellOneVolume = 20;

	private static final int tradeDate = 30;

	private static final int tradeTime = 31;

	@Override
	public List<DStockRealtime> getRealTimeDateByCode(int timePoint, List<String> codes) {
		List<DStockRealtime> retList = null;
		String strCodes = StringUtils.join(",", codes.toArray(new String[0]));//translateCode(codes);
		String url = config.getRealtimeApiURL() + strCodes;
		String result = HttpClientUtil.sendHttpGet(url);
		String[] items = result.split("\n");
		retList = new ArrayList<>(items == null ? 0 : items.length);
		if (items != null) {
			for (int i = 0; i < items.length; i++) {
				String item = items[i];
				try {
					DStockRealtime retItem = paraseFromString(item);
					retItem.setTradeTimePoint(timePoint);
					if (retItem != null) {
						retList.add(retItem);
					}
				} catch (Exception e) {
					log.error("解析实时数据失败", e);
				}
			}
		}
		return retList;
	}

	private DStockRealtime paraseFromString(String item) {
		DStockRealtime stockRealtimeData = new DStockRealtime();
		String[] strParts = item.split("=");
		if (strParts == null || strParts.length < 2) {
			return null;
		}
		String realData = strParts[1].replace("\"", "");
		String header = strParts[0];
		String code = header.split("hq_str_")[1].substring(2);
		String[] realDataArr = realData.split(",");

		stockRealtimeData.setStockCode(code);
		stockRealtimeData.setStockName(realDataArr[stockName]);
		stockRealtimeData.setBuyingPrice(Double.valueOf(realDataArr[buyingPrice]));
		stockRealtimeData.setClosingPriceY(Double.valueOf(realDataArr[closingPriceY]));
		stockRealtimeData.setCurrentPrice(Double.valueOf(realDataArr[currentPrice]));
		stockRealtimeData.setHighestPrice(Double.valueOf(realDataArr[highestPrice]));
		stockRealtimeData.setLowestPrice(Double.valueOf(realDataArr[lowestPrice]));
		stockRealtimeData.setOpeningPrice(Double.valueOf(realDataArr[openingPrice]));
		stockRealtimeData.setSellingPrice(Double.valueOf(realDataArr[sellingPrice]));
		stockRealtimeData.setTradeAmount(Double.valueOf(realDataArr[tradeAmount]));
		stockRealtimeData.setTradeDate(DateUtils.parseDate(realDataArr[tradeDate], "yyyy-MM-dd"));
		stockRealtimeData.setTradeTime(realDataArr[tradeTime]);
		stockRealtimeData.setBuyOneVolume(Long.valueOf(realDataArr[buyOneVolume]));
		stockRealtimeData.setSellOneVolume(Long.valueOf(realDataArr[sellOneVolume]));
		stockRealtimeData.setTradeVolume(Long.valueOf(realDataArr[tradeVolume]));
		return stockRealtimeData;
	}

	@Override
	public List<DStockRealtime> getRealtimeData(int timepoint) {
		List<DStockRealtime> res = Lists.newArrayList();
		List<String> allCodes = profileMapper.loadAllStockCodesForSina();
		if (CollectionUtils.isEmpty(allCodes)) {
			return res;
		}
		int pageSize = config.getRealtimeApiPageSize();
		int listSize = allCodes.size();
		int pageCnt = listSize % pageSize == 0 ? listSize / pageSize : listSize / pageSize + 1;
		for (int i = 1; i <= pageCnt; i++) {
			int startIndex = (i - 1) * pageSize;
			int endIndex = startIndex + pageSize;
			if (endIndex > listSize) {
				endIndex = listSize;
			}
			List<String> subItems = allCodes.subList(startIndex, endIndex);
			List<DStockRealtime> realTimeData = getRealTimeDateByCode(timepoint, subItems);
			if (realTimeData != null && !realTimeData.isEmpty()) {
				DStockRealtime data = realTimeData.get(0);
				if (!DateUtils.format(new Date()).equals(DateUtils.format(data.getTradeDate()))) {
					return res; //非交易日
				}
			}
			res.addAll(realTimeData);
		}
		return res;
	}

}
